package com.travel.api.service.user.impl

import com.github.pagehelper.PageHelper
import com.github.pagehelper.PageInfo
import com.travel.api.beans.request.BaseRequest
import com.travel.api.beans.request.user.LoginRequest
import com.travel.api.beans.request.user.RegisterRequest
import com.travel.api.beans.user.SysUser
import com.travel.api.utils.ResultConstant
import com.travel.api.enums.user.AccountEnum
import com.travel.api.enums.user.UserFlagEnum
import com.travel.api.enums.user.UserTypeEnum
import com.travel.api.interfaces.SysUserMapper
import com.travel.api.service.BaseService
import com.travel.api.service.user.UserService
import com.travel.api.utils.CommonUtil
import com.travel.api.utils.MD5Util
import com.travel.api.utils.RedisUtil
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.util.CollectionUtils
import org.springframework.util.StringUtils

import javax.servlet.http.HttpServletRequest
import java.util.Date

/**
 * @ClassName UserServiceImpl
 * @Author liguangyao
 * @Date 13/8/18 下午3:21
 * @Version 1.0
 */
@Service
class UserServiceImpl : UserService, BaseService() {

    private val log = LoggerFactory.getLogger(UserServiceImpl::class.java)

    companion object {

        private val TOKEN_PREFIX = "TOKEN::PREFIX::"
    }

    @Autowired
    private val sysUserMapper: SysUserMapper? = null

    override fun list(request: BaseRequest): PageInfo<*> {
        PageHelper.startPage<Any>(request.getPageNo(), request.getPageSize())
        val userList = sysUserMapper!!.selectAll()
        return PageInfo(userList)
    }

    @Transactional
    override fun register(request: RegisterRequest): Map<String, Any> {
        val sysUser = SysUser()
        sysUser.mobile = request.mobile
        val sysUserList = sysUserMapper!!.select(sysUser)
        if (!sysUserList.isEmpty()) {
            // 判断手机号是否已经注册, 若已经注册则返回账号已经注册
            return fail(ResultConstant.MOBILE_ALREADY_REGISTER, "手机号已被使用")
        }
        sysUser.id = CommonUtil.getId()
        sysUser.userType = UserTypeEnum.ORDINARY_USER.value // 普通用户类型
        sysUser.password = MD5Util.generate(request.password) // 密码加盐
        sysUser.name = request.mobile // 默认使用手机号
        sysUser.loginFlag = AccountEnum.YES_LOGIN.value
        sysUser.createBy = request.mobile
        sysUser.createDate = Date()
        sysUser.updateBy = request.mobile
        sysUser.updateDate = Date()
        sysUser.delFlag = UserFlagEnum.NO_CANCEL.value
        log.info("[用户注册]SysUser: {}", sysUser)
        val register = sysUserMapper.insert(sysUser)
        return if (register == 1)
            success()
        else
            fail(ResultConstant.USER_REGISTER_ERROR, "用户注册失败")
    }

    override fun login(request: LoginRequest, servletRequest: HttpServletRequest): Map<String, Any> {
        val sysUser = SysUser()
        // 判断是手机号登录还是邮箱登录
        val username = request.username
        var sysUserList: List<SysUser>? = null
        if (username!!.contains("@")) { // 邮箱登录
            sysUser.email = request.username
            sysUserList = sysUserMapper!!.select(sysUser)
            if (sysUserList!!.isEmpty()) {
                return CommonUtil.getFailResult(ResultConstant.USERNAME_OR_PASSWORD_EOOR, "账号或密码错误")
            }
        } else {
            sysUser.mobile = request.username // 手机号登录
            sysUserList = sysUserMapper!!.select(sysUser)
            if (sysUserList!!.isEmpty()) {
                return fail(ResultConstant.USERNAME_OR_PASSWORD_EOOR, "账号或密码错误")
            }
        }
        // 判断密码是否正确
        val sqlSysUser = sysUserList[0]
        val md5Password = sqlSysUser.password
        if (!MD5Util.verify(request.password, md5Password)) {
            return fail(ResultConstant.USERNAME_OR_PASSWORD_EOOR, "账号或密码错误")
        }

        // 判断账号状态
        val delFlag = sqlSysUser.delFlag
        if(UserFlagEnum.YES_CANCEL.value == delFlag) {
            return fail(ResultConstant.USER_CANCEL,"账号已注销")
        }

        // 判断登录状态
        val loginFlag = sqlSysUser.loginFlag
        if(AccountEnum.LOCK_LOGIN.value == loginFlag) {
            return fail(ResultConstant.USER_LOCK_LOGIN,"账户已锁,请联系管理员")
        }
        if(AccountEnum.NO_LOGIN.value == loginFlag) {
            return fail(ResultConstant.USER_NO_LOGIN,"账户当前不允许登录,请联系管理员")
        }

        sqlSysUser.loginIp = servletRequest.getAttribute("IP").toString()
        sqlSysUser.loginDate = Date()
        sqlSysUser.updateDate = Date()
        val update = sysUserMapper.updateByPrimaryKeySelective(sqlSysUser)
        // 创建Token 存入Redis中有效时间1小时并返回
        val token = CommonUtil.getId()
        RedisUtil.setValue(TOKEN_PREFIX + token, sqlSysUser.mobile, 60 * 60)
        // 返回前端Token值
        log.info("[用户登录]账号:{},Token:{}", request.username, token)
        return success("登录成功", token)
    }

    override fun judgeToken(token: String): Boolean {
        val reToken = RedisUtil.get(TOKEN_PREFIX + token)
        return StringUtils.isEmpty(reToken)
    }

    override fun logout(token: String): Boolean {
        return RedisUtil.deleteKey(TOKEN_PREFIX + token)
    }

    override fun getUserInfo(mobile: String): SysUser? {
        val sysUser = SysUser()
        sysUser.mobile = mobile
        val sqlSysUser = sysUserMapper!!.select(sysUser)
        if(!CollectionUtils.isEmpty(sqlSysUser)) {
            return sqlSysUser[0]
        }
        return null
    }
}
